/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 *
 * @author Chango
 */
public class Decompressor {
    private String source,destiny;
    private FileOutputStream writer;
    private FileInputStream reader;

    public Decompressor(String source, String destiny){
        this.destiny=destiny;
        this.source=source;
    }

    public void decompress()throws IOException, FileNotFoundException{
        String line="",tempAux="",ext="",codes[];
        int size=0,countBytes=0,byteReaded=0;
        long numBytes=0;
        byte tempTable[];

        reader=new FileInputStream(source);
        //leer tabla
        for(int i=0; i<4; i++)
			numBytes+=(reader.read()*Math.pow(256,i));
		for(int i=0; i<4; i++)
			ext+=(char)reader.read();

	size=reader.read();

        tempTable = new byte[size];
		codes = new String[size];
		writer = new FileOutputStream(destiny+ext);

		for(int i=0; i<size; i++){
			tempTable[i]= (byte)reader.read();
			codes[i]= createCodigo((int)reader.read(), reader.read());
		}
                do {
			byteReaded=reader.read();

			if(byteReaded!=-1){
				line= createASCII(byteReaded);

				for(int i=0; i<line.length(); i++){
					tempAux+=line.charAt(i);

					for(int j=0; j<codes.length; j++){

						if(tempAux.equals(codes[j]) && countBytes < numBytes){
							writer.write(tempTable[j]);
							countBytes++;
							tempAux="";
							break;
						}
					}
				}
			}
		}while(byteReaded!=-1);
		reader.close();
		writer.close();
	}

    private String createCodigo(int num, int cantZero){

		String bin=decToBin(num);
		String code= reverse(bin, bin.length()-1);

		for(int i=0; i< cantZero; i++){
			code+="0";
		}
		return reverse(code,code.length()-1);
	}

    private String createASCII(int num){

		String bin=decToBin(num);
		String ascii=reverse(bin, bin.length()-1);

		for(int i=0; ascii.length()<8; i++)ascii+="0";

		return reverse(ascii, ascii.length()-1);

	}

    private String decToBin(int num){

		String ans="";

		while(num>=1){
			ans+= (char)((num%2)+ 48);
			num= num/2;
		}
		return reverse(ans, ans.length()-1);
	}

    private String reverse(String p, int i){
		if(i<0)
			return "";
		else
			return ""+ p.charAt(i) + reverse(p, i-1);
	}

}
